using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace EuropeEngulfed.NET
{
    class DeploymentMove : Move
    {
        private MapInfo.CountryID countryForcePool;
        private PlayingPiece pieceDeployed;
        private MapInfo.RegionID regionDeployedTo;

        public PlayingPiece PieceDeployed
        {
            get
            {
                return pieceDeployed;
            }
        }

        public MapInfo.RegionID RegionDeployed
        {
            get
            {
                return regionDeployedTo;
            }
        }

        public DeploymentMove(GameTurn.GameDate gameDate, GameTurn.GamePhase gamePhase, GameTurn.GameSubPhase gameSubPhase, MapInfo.CountryID countryForcePool, PlayingPiece pieceDeployed, MapInfo.RegionID regionDeployedTo)
            : base(gameDate, gamePhase, gameSubPhase)
        {
            this.countryForcePool = countryForcePool;
            this.pieceDeployed = pieceDeployed;
            this.regionDeployedTo = regionDeployedTo;
        }

        protected override void ProcessMove(GameState gameState)
        {
            if(pieceDeployed is Block)
            {
                Block blockDeployed = (Block)pieceDeployed;
                gameState.PlaceBlockFromPoolIntoLandRegion(this.regionDeployedTo, blockDeployed.CountryOwner, blockDeployed.getBlockType(), blockDeployed.MaxStrength, blockDeployed.CurrentStrength);
            }
            else
            {
                GroundSupportUnit GSUDeployed = (GroundSupportUnit)pieceDeployed;
                gameState.PlaceGSUFromPoolIntoLandRegion(regionDeployedTo, GSUDeployed.CountryOwner);
            }
        }

        public override bool IsLegal(IGameStateInfoProvider gameStateInfoProvider, ref string ruleString)
        {
            if (MapInfo.IsLandRegion(regionDeployedTo))
            {
                LandRegion landRegion = (LandRegion)MapInfo.GetRegion(regionDeployedTo);
                if (pieceDeployed.CountryOwner == landRegion.OriginalCountry || (landRegion.OriginalCountry == MapInfo.CountryID.France && pieceDeployed.CountryOwner == MapInfo.CountryID.VichyFrance))
                {
                    if (pieceDeployed.CountryOwner == MapInfo.CountryID.VichyFrance)
                    {
                        if(MapInfo.IsInAfrica(regionDeployedTo))
                        {
                            if(gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Morocco).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Oran).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Algiers).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.EastAlgeria).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Tunisia).Count > 0)
                            {
                                ruleString = "Only one Vichy unit can be deployed in Africa... see 9.522";
                                return false;
                            }
                        }
                        else if(regionDeployedTo == MapInfo.RegionID.Lebanon || regionDeployedTo == MapInfo.RegionID.Syria)
                        {
                            if(gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Lebanon).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Syria).Count > 0)
                            {
                                ruleString = "Only one Vichy unit can be deployed in the Middle East... see 9.522";
                                return false;
                            }
                        }
                        else
                        {
                            if(gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.FrenchAlps).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Lyon).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Marseille).Count > 0
                                || gameStateInfoProvider.GetRegionsAxisBlockList(MapInfo.RegionID.Corsica).Count > 0)
                            {
                                ruleString = "Only one Vichy unit can be deployed in the Metropolitan France or Corsica... see 9.522";
                                return false;
                            }
                        }
                    }

                    if(pieceDeployed.CountryOwner == MapInfo.CountryID.Norway)
                    {
                        if(regionDeployedTo != MapInfo.RegionID.Oslo && regionDeployedTo != MapInfo.RegionID.Trondheim)
                        {
                            ruleString = "A Norwegian unit must be deployed at each invasion site";
                            return false;
                        }
                        else if(regionDeployedTo == MapInfo.RegionID.Oslo && gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Oslo).Count > 0)
                        {
                            ruleString = "A Norwegian unit must be deployed at each invasion site";
                            return false;
                        }
                        else if(regionDeployedTo == MapInfo.RegionID.Trondheim && gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Trondheim).Count > 0)
                        {
                            ruleString = "A Norwegian unit must be deployed at each invasion site";
                            return false;
                        }

                    }

                    if(pieceDeployed.CountryOwner == MapInfo.CountryID.Yugoslavia)
                    {
                        if(regionDeployedTo == MapInfo.RegionID.Belgrade)
                        {
                            if (gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Belgrade).Count > 0)
                            {
                                if (gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Zagreb).Count == 0 || gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Skopje).Count == 0)
                                {
                                    ruleString = "At least 1 Yugoslav unit must deployed in each home area";
                                    return false;
                                }
                            }
                        }
                        else if (regionDeployedTo == MapInfo.RegionID.Zagreb)
                        {
                            if (gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Zagreb).Count > 0)
                            {
                                if (gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Belgrade).Count == 0 || gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Skopje).Count == 0)
                                {
                                    ruleString = "At least 1 Yugoslav unit must deployed in each home area";
                                    return false;
                                }
                            }
                        }
                        else if (regionDeployedTo == MapInfo.RegionID.Skopje)
                        {
                            if (gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Skopje).Count > 0)
                            {
                                if (gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Zagreb).Count == 0 || gameStateInfoProvider.GetRegionsAlliedBlockList(MapInfo.RegionID.Belgrade).Count == 0)
                                {
                                    ruleString = "At least 1 Yugoslav unit must deployed in each home area";
                                    return false;
                                }
                            }
                        }
                    }

                    return true;
                }
                else
                    ruleString = "Cannot deploy a piece to a non-home area";
            }
            else
                ruleString = "Cannot deploy to a sea area";
            return false;
        }

        public override System.Xml.XmlNode Serialise(System.Xml.XmlDocument xml)
        {
            System.Xml.XmlNode nodeToReturn = xml.CreateElement("Move");
            System.Xml.XmlAttribute typeAttr = xml.CreateAttribute("Type");
            System.Xml.XmlNode pieceDeployedNode = xml.CreateElement("pieceDeployed");
            System.Xml.XmlAttribute countryForcePoolAttr = xml.CreateAttribute("countryForcePool");
            System.Xml.XmlAttribute regionDeployedToAttr = xml.CreateAttribute("regionDeployedTo");

            nodeToReturn.AppendChild(gameTurn.Serialise(xml));
            typeAttr.Value = this.GetType().ToString();
            countryForcePoolAttr.Value = Enum.GetName(countryForcePool.GetType(), countryForcePool);
            regionDeployedToAttr.Value = Enum.GetName(regionDeployedTo.GetType(), regionDeployedTo);

            nodeToReturn.Attributes.Append(typeAttr);
            nodeToReturn.Attributes.Append(countryForcePoolAttr);
            nodeToReturn.Attributes.Append(regionDeployedToAttr);
            if(pieceDeployed is Block)
            {
                pieceDeployedNode.AppendChild(((Block)pieceDeployed).Serialise(xml));
            }
            else if(pieceDeployed is GroundSupportUnit)
            {
                pieceDeployedNode.AppendChild(((GroundSupportUnit)pieceDeployed).Serialise(xml));
            }
            nodeToReturn.AppendChild(pieceDeployedNode);

            return nodeToReturn;
        }

        public new static Move Deserialise(System.Xml.XmlNode node)
        {
            if (node.Attributes["Type"].Value == typeof(DeploymentMove).ToString() && node.Name == "Move")
            {
                GameTurn parsedGameTurn = GameTurn.Deserialise(node.SelectSingleNode("GameTurn"));
                DeploymentMove deploymentMoveToReturn = new DeploymentMove(parsedGameTurn.CurrentGameDate, parsedGameTurn.CurrentGamePhase, parsedGameTurn.CurrentGameSubPhase, (MapInfo.CountryID)Enum.Parse(typeof(MapInfo.CountryID), node.Attributes["countryForcePool"].Value), PlayingPiece.Deserialise(node.SelectSingleNode("pieceDeployed")), (MapInfo.RegionID)Enum.Parse(typeof(MapInfo.RegionID), node.Attributes["regionDeployedTo"].Value));
                return deploymentMoveToReturn;
            }
            else
                throw new InvalidOperationException();
        }

        public override System.Windows.Forms.TreeNode GetMoveTreeNode(System.Windows.Forms.TreeView treeView)
        {
            System.Windows.Forms.TreeNode treeNode = new System.Windows.Forms.TreeNode("deployment in " + MapInfo.GetRegionName(this.regionDeployedTo) + " for " + Enum.GetName(this.countryForcePool.GetType(), this.countryForcePool));
            if (!treeView.ImageList.Images.ContainsKey(this.pieceDeployed.GetTreeViewImageListKey(true)))
            {
                if (pieceDeployed is Block)
                {
                    Bitmap b = new Bitmap(treeView.ImageList.ImageSize.Width, treeView.ImageList.ImageSize.Height);
                    Graphics g = Graphics.FromImage(b);
                    PlayingPieceGraphics.PaintBlockFace(g, (Block)pieceDeployed, new Rectangle(0, 0, treeView.ImageList.ImageSize.Width, treeView.ImageList.ImageSize.Height), true);
                    treeView.ImageList.Images.Add(pieceDeployed.GetTreeViewImageListKey(true), b);
                }
                else if (pieceDeployed is GroundSupportUnit)
                {
                    Bitmap b = new Bitmap(treeView.ImageList.ImageSize.Width, treeView.ImageList.ImageSize.Height);
                    Graphics g = Graphics.FromImage(b);
                    PlayingPieceGraphics.PaintGSUFace(g, (GroundSupportUnit)pieceDeployed, new Rectangle(0, 0, treeView.ImageList.ImageSize.Width, treeView.ImageList.ImageSize.Height), false);
                    treeView.ImageList.Images.Add(pieceDeployed.GetTreeViewImageListKey(true), b);
                }
            }
            treeNode.ImageIndex = treeView.ImageList.Images.IndexOfKey(pieceDeployed.GetTreeViewImageListKey(true));
            treeNode.SelectedImageIndex = treeNode.ImageIndex;

            return treeNode;
        }
        public override string GetStringForNetworkMessage()
        {
            return "Deployed " + this.pieceDeployed.GetHiddenStringDescription() + " in " + Enum.GetName(typeof(MapInfo.RegionID), this.regionDeployedTo);
        }
    }
}
